function process_xml(xml) -- 解析XML
    local text = {}
    local styles = {}

    -- 提取样式信息
    for style in xml:gmatch("<w:style(.-)</w:style>") do
        local name = style:match("w:name w:val=\"(.-)\"")
        local id = style:match("w:styleId=\"(.-)\"")
        local fill = style:match("w:fill=\"(.-)\"") or "No fill"
        table.insert(styles, { name = name, id = id, fill = fill })
    end

    -- 判断是否是标题
    local function is_title(id)
        for _, style in ipairs(styles) do
            if style.id == id then
                return string.match(style.name, "^heading %d*$") or style.name == "Subtitle" or style.name == "Title"
            end
        end
        return false
    end

    -- 解析段落
    for wp in string.gmatch(xml, "<w:p>(.-)</w:p>") do
        local line = {}
        local p_style_id = string.match(wp, "<w:pStyle w:val=\"(.-)\"")
        local has_p_style = string.find(wp, "<w:pStyle ") ~= nil
        for wr in string.gmatch(wp, "<w:r>(.-)</w:r>") do
            local r_style_id = string.match(wr, "<w:rStyle w:val=\"(.-)\"")
            local has_shd = string.find(wr, "<w:shd") ~= nil
            local has_color = string.find(wr, "w:color") ~= nil and not string.find(wr, 'w:color w:val="000000"')
            local has_strike = string.find(wr, "<w:strike/>") ~= nil

       
            for wt in string.gmatch(wr, "<w:t>(.-)</w:t>") do
      
                if wt:find("^EQ") then
                    wt = ""
                end
                if wt ~= "" then
                    if has_strike then
                        wt = "○" .. wt .. "○"
                    else
                        if has_p_style and is_title(p_style_id) then
                            wt = "☆" .. wt .. "☆"
                        end
                    end
                    table.insert(line, wt)
                end
            end
   
        end
        if #line > 0 then
            table.insert(text, "\n\n" .. table.concat(line))
        end
    end
    return table.concat(text)
end

function format_text_from_xml(xml)  --最新分组
    local binary_table = { "1" } -- 初始化表并插入第一个 "1"
    local text = process_xml(xml)
    if not text or text == "" then return nil end
    for line in text:gmatch("[^\r\n]+") do
        if line ~= "○" and line ~= "○○" and line ~= "○○○" then
            line = line:gsub(" ", ""):gsub(" ", ""):gsub("　", "")
            table.insert(binary_table, line)  -- 只有不为 "1" 时才插入
        end
    end
    table.insert(binary_table, "☆ 文本结束 ☆")
    return binary_table
end

function copy_file(source_path, dest_path) -- 复制文件
    local in_file = io.open(source_path, "rb")
    if not in_file then
        return false, "无法打开源文件: " .. source_path
    end

    local out_file = io.open(dest_path, "wb")
    if not out_file then
        in_file:close()
        return false, "无法打开目标文件: " .. dest_path
    end

    local data = in_file:read("*a")
    out_file:write(data)
    in_file:close()
    out_file:close()

    return true
end

function open_file(file_path, ext) -- 打开Word文件并转换为XML
    local dest_path = reaper.GetResourcePath() .. "/111" .. ext
    local retval, desc = copy_file(file_path, dest_path)
    if not retval then
        return
    end
    local transfer_xml = reaper.GetResourcePath() .. "/transfer.xml"
    local ps_script = [[
    param (
        [string]$inputPath,
        [string]$outputPath
    )

    $inputPath = [System.Text.Encoding]::UTF8.GetString([System.Text.Encoding]::Default.GetBytes($inputPath))
    $outputPath = [System.Text.Encoding]::UTF8.GetString([System.Text.Encoding]::Default.GetBytes($outputPath))

    $word = New-Object -ComObject "kwps.Application"
    $doc = $word.Documents.Open($inputPath)
    $doc.SaveAs([Ref] $outputPath, [Ref] 11)
    $word.Quit()
    $word = $null
    ]]

    local ps_path = reaper.GetResourcePath() .. "/ps.ps1"
    local ps_file = io.open(ps_path, "w")
    ps_file:write(ps_script)
    ps_file:close()
    local is_win = reaper.GetOS():find("Win")
    if not is_win then
        os.execute("powershell.exe -ExecutionPolicy Bypass -WindowStyle Hidden -File \"" ..
            ps_path .. "\" -inputPath \"" .. dest_path .. "\" -outputPath \"" .. transfer_xml .. "\"")
    else
        local cmd = 'powershell -ExecutionPolicy Bypass -WindowStyle Hidden -File "' ..
            ps_path .. '" -inputPath "' .. dest_path .. '" -outputPath "' .. transfer_xml .. '"'
        reaper.ExecProcess(cmd, 0)
    end
    local file = io.open(transfer_xml, "r")
    if not file then
        return
    end
    local xml = file:read("*all")
    file:close()
    os.remove(ps_path)
    os.remove(transfer_xml)
    os.remove(dest_path)

    local texts = format_text_from_xml(xml)
    return texts
end